﻿using System;
using System.Linq;
using System.Collections.Generic;
using System.ServiceModel;
using System.ServiceModel.Description;
using System.ServiceModel.Web;
using Natural.Helpers;
using Natural.Managers;
using Natural.Model;
using Natural.Providers;
using Extensions;
using System.Reflection;

namespace TestConsole
{
    //http://localhost:8000/Service/Test?id=12
    //http://localhost:8000/Service/Invoke/"{Entity:'Party';Action:'Get'}"
    
    class Program
    {
        static void Main(string[] args)
        {
            TestInvoke();
            Console.ReadKey();
        }
        
        static void TestSerialization()
        {
            //DeviceLocation dl = new DeviceLocation() { Date = DateTime.Now, DeviceId = 2, Latitude = 1, Longitude = 2 };
            //InvokeRequest ir = new InvokeRequest();
            //ir.Commands = new List<Command>();
            //ir.Commands.Add(new Command() { Action = "Update", Entity = "Device.Location", Parameters = new string[] { Facade.Solve<Serializer>().Serialize(dl) } });
            //string json = Facade.Solve<Serializer>().Serialize(ir);
            //string json2 = "{\"Commands\":[{\"Entity\":\"Device.Location\",\"Action\":\"Update\",\"Parameters\":[\"{\\\"DeviceId\\\":2,\\\"Date\\\":\\\"2014-10-28T02:46:22\\\",\\\"Latitude\\\":1.0,\\\"Longitude\\\":2.0}\"]}]}";
            

            Expression expression = new Expression();
            expression.Text = "SELECT VALUE e FROM Device AS e WHERE e.DeviceTypeId = @DeviceTypeId";
            expression.Parameters = new Parameters() { { "DeviceTypeId", 1 } };
            string json = Serializer.Serialize(expression);

            Dictionary<string, object> dic = Serializer.Deserialize<Dictionary<string, object>>(json);
            int count = dic.Count;

            Expression expression2 = Serializer.Deserialize<Expression>(json);

            Dictionary<string, object> dic2 = new Dictionary<string, object>();
            dic2.Add("a", 1);
            dic2.Add("b", "b");

            string json2 = Serializer.Serialize(dic2);

            Dictionary<string, object> deserializedDictionary1 = (Dictionary<string, object>)Serializer.Deserialize(json2, typeof(object));
            Dictionary<string, object> deserializedDictionary2 = Serializer.Deserialize<Dictionary<string, object>>(json2);
            object objDeserialized = Serializer.DeserializeObject(json2);

        }
        static void TestActuator()
        {
            InvokeContext context = new InvokeContext();

            Expression expression = new Expression();
            expression.Text = " this.DeviceTypeId = @DeviceTypeId";
            expression.Parameters = new Parameters() { { "DeviceTypeId", 1 } };
            expression.Includes = "DeviceType";
            Device[] devices = Executor.Get<Device>(context,expression);
            devices = Executor.Get<Device>(context, expression);

            //Device.Get(1,{Name:'Flavio'})
            //Expression expression2 = new Expression();
            //expression2.Text = "SELECT e.Name,e.Code FROM Device AS e WHERE e.DeviceTypeId = @DeviceTypeId";
            //expression2.Parameters = new Parameters() { { "DeviceTypeId", 1 } };
            //List<object[]> result = Actuator.Execute(null,"Query", expression2, "DeviceType") as List<object[]>;

            //Actuator.Excute("Party", "Update", new Party() { Name = "Rocio" });
            Party party = new Party() { Name = "Rocio" };
            Executor.Update<Party>(context, party);  
            
            string expressionSerialized = Serializer.Serialize(expression);            
            InvokeRequest request = new InvokeRequest() { Commands = new Command[]{new Command() { Entity = "Device", Action = "Get", Parameters = new string[] { expressionSerialized } }} };
            InvokeResponse response = Invoker.Invoke(request);
        }
        static void TestInvoke()
        {
            /*
            1- Actualizar la posicion
            2- Actualizar estado
             *  
             *   
             * 
             * 
             */
            InvokeRequest test = new InvokeRequest()
                                 { Session = new SessionInfo(){ User ="flaviolrita"}
                                 , Commands = new  Command[]{ new Command(){ Entity="Device", Action="Activate", Parameters = new string[]{"2"}  }
                                                            , new Command(){ Entity="Device.Location",Action="Update", Parameters = new string[]{Serializer.Serialize(new DeviceLocation(){ DeviceId=2,Date=DateTime.Now,Latitude=1,Longitude=3 })} }}
                                 };


            string json = Serializer.Serialize(test);
            //string json = "{\"Commands\":[{\"Entity\":\"Device.Location\",\"Action\":\"Update\",\"Parameters\":[\"{\\\"DeviceId\\\":2,\\\"Date\\\":\\\"2014-10-28T02:46:22\\\",\\\"Latitude\\\":1.0,\\\"Longitude\\\":2.0}\"]}]}";
            InvokeRequest request = Serializer.Deserialize<InvokeRequest>(json);
            InvokeResponse response = Invoker.Invoke(request);
        }

        static void Questions()
        { 
           //// Listar entities.
           // Attributes.Entity entity = new Attributes.Entity();  
           // foreach (EntityInfo entityInfo in Runtime.Info.Entities.Where(p => p.Value.IsRoot).Select(p => p.Value))
           // { 
           //     Type type = Type.GetType(entityInfo.TypeName);
           //     foreach(PropertyInfo propertyInfo in type.GetProperties().Where(p=> ReflectionHelper.Contain(p.PropertyType, entity)))
           //     {
           //         propertyInfo.Name;
           //     }
                
           // }



            
        }


        
        static void StartService()
        {
            string baseAddress = string.Format("http://{0}:8000/srv", Environment.MachineName);
            ServiceHost host = new ServiceHost(typeof(InvokerService), new Uri(baseAddress));
            host.AddServiceEndpoint(typeof(IInvokerService), new WebHttpBinding(), "").Behaviors.Add(new WebHttpBehavior());
            host.Open();
            Console.WriteLine("Servicio iniado...");
            Console.ReadKey();
        }

    }



     #region Service
    [ServiceContract]
    public interface IInvokerService
    {
        [WebInvoke(Method = "POST", UriTemplate = "/invoke", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Wrapped)]
        InvokeResponse Invoke(InvokeRequest request);
    }
    public class InvokerService : IInvokerService
    {
        public InvokeResponse Invoke(InvokeRequest request)
        {
            return Invoker.Invoke(request);
        }
    }
     #endregion
}
